package com.ym521.emojipack.keyboard.fragment;

import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;

import com.ym521.emojipack.R;
import com.ym521.emojipack.emoji.EmojiPack;
import com.ym521.emojipack.keyboard.EmoiiPackClickListener;
import com.ym521.emojipack.keyboard.EmojiPackRecentManager;
import com.ym521.emojipack.keyboard.adapter.EmojiPackGroupAdapter;
import com.ym521.emojipack.keyboard.adapter.EmojiPackFragmentPagerAdapter;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Ym
 */
public final class EmojiBoardFragment extends Fragment implements
        View.OnClickListener, EmoiiPackClickListener {

    private static String TAG = "EmojiBoardFragment";
    private EditText editText;
    private ViewPager2 mViewPager2;
    private ImageView ivEmojis;
    private ImageView ivRecents;
    private ImageView ivBackspace;

    private int mEmojiTabLastSelectedIndex = -1;
    private EmojiPackFragmentPagerAdapter mEmojisAdapter;
    private EmojiPackRecentManager mRecentsManager;
    private List<Fragment> fragmentList;

    private int theme;

    public static EmojiBoardFragment newInstance(int theme) {
        EmojiBoardFragment fragment = new EmojiBoardFragment();
        fragment.setEmojiTheme(theme);
        return fragment;
    }
    public void setEmojiTheme(int theme) {
        this.theme = theme;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.emojipack_fragment, container, false);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        mViewPager2 = view.findViewById(R.id.vp2_emoji);
        ivBackspace = view.findViewById(R.id.iv_backspace);
        mViewPager2.registerOnPageChangeCallback(changeCallback);
        fragmentList = new ArrayList<>();
        EmojiPackRecentFragment fragment01 = EmojiPackRecentFragment.newInstance();
        fragment01.setEmojiClickedListener(this);
        fragmentList.add(fragment01);
        EmojiPackFragment fragment02 = EmojiPackFragment.newInstance(theme);
        fragment02.setEmojiClickedListener(this);
        fragmentList.add(fragment02);
        mEmojisAdapter = new EmojiPackFragmentPagerAdapter(this, fragmentList);
        mViewPager2.setAdapter(mEmojisAdapter);
        mViewPager2.setUserInputEnabled(false);
        mViewPager2.setOffscreenPageLimit(fragmentList.size());
        ivRecents = view.findViewById(R.id.iv_recents);
        ivRecents.setOnClickListener(this);
        ivEmojis = view.findViewById(R.id.iv_emoji);
        ivEmojis.setOnClickListener(this);
        ivBackspace.setOnTouchListener(new RepeatListener(800, 50, (v) ->{
            backspace();
        }));

        mRecentsManager = EmojiPackRecentManager.getInstance(view.getContext());
        int page = mRecentsManager.getRecentPage();
        if (page == 0 && mRecentsManager.size() == 0) {
            page = 1;
        }
        if (page == 0) {
            onSelected(page);
        } else {
            mViewPager2.setCurrentItem(page, false);
        }
        Log.e(TAG,"onViewCreated");
    }

    public void input(EditText editText) {
        if (editText == null)
            return;
        this.editText = editText;
    }

    private void backspace() {
        if (this.editText != null) {
            KeyEvent event = new KeyEvent(0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
            editText.dispatchKeyEvent(event);
        }
    }


    @Override
    public void onEmojiClicked(EmojiPack emojiPack) {
        if (editText == null)
            return;
        mRecentsManager.push(emojiPack);
        editText.requestFocus();
        int start = editText.getSelectionStart();
        int end = editText.getSelectionEnd();
        if (start < 0) {
            editText.append(emojiPack.getEmoji());
        } else {
            editText.getText().replace(Math.min(start, end), Math.max(start, end), emojiPack.getEmoji(), 0, emojiPack.getEmoji().length());
        }
    }

    private ViewPager2.OnPageChangeCallback changeCallback = new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageSelected(int position) {
            onSelected(position);
        }
    };


    private void onSelected(int position) {
        if (mEmojiTabLastSelectedIndex == position) {
            return;
        }
        ivRecents.setSelected(position == 0);
        ivEmojis.setSelected(position == 1);
        mEmojiTabLastSelectedIndex = position;
        mRecentsManager.setRecentPage(position);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.iv_recents) {
            v.setSelected(!v.isSelected());
            mViewPager2.setCurrentItem(0);
        }
        if (v.getId() == R.id.iv_emoji) {
            v.setSelected(!v.isSelected());
            mViewPager2.setCurrentItem(1);
        }
    }

    public static class RepeatListener implements View.OnTouchListener {

        private Handler handler = new Handler();

        private int initialInterval;
        private final int normalInterval;
        private final View.OnClickListener clickListener;

        private Runnable handlerRunnable = new Runnable() {
            @Override
            public void run() {
                if (downView == null) {
                    return;
                }
                handler.removeCallbacksAndMessages(downView);
                handler.postAtTime(this, downView, SystemClock.uptimeMillis() + normalInterval);
                clickListener.onClick(downView);
            }
        };

        private View downView;

        /**
         * @param initialInterval 第一次单击事件之前的间隔
         * @param normalInterval  第二次和随后单击之前的间隔
         *                        事件
         * @param clickListener   将被调用的OnClickListener
         *                        周期性地
         */
        public RepeatListener(int initialInterval, int normalInterval, View.OnClickListener clickListener) {
            if (clickListener == null)
                throw new IllegalArgumentException("null runnable");
            if (initialInterval < 0 || normalInterval < 0)
                throw new IllegalArgumentException("negative interval");

            this.initialInterval = initialInterval;
            this.normalInterval = normalInterval;
            this.clickListener = clickListener;
        }

        public boolean onTouch(View view, MotionEvent motionEvent) {
            switch (motionEvent.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    downView = view;
                    handler.removeCallbacks(handlerRunnable);
                    handler.postAtTime(handlerRunnable, downView, SystemClock.uptimeMillis() + initialInterval);
                    clickListener.onClick(view);
                    view.setSelected(true);
                    return true;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_OUTSIDE:
                    handler.removeCallbacksAndMessages(downView);
                    downView = null;
                    view.setSelected(false);
                    return true;
            }
            return false;
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mViewPager2.unregisterOnPageChangeCallback(changeCallback);
        fragmentList.clear();
        fragmentList = null;
    }
}
